/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package extensions.romario.server;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.NumberFormat;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.niftygui.NiftyJmeDisplay;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;

import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.controls.DropDown;
import de.lessvoid.nifty.elements.Element;
import de.lessvoid.nifty.elements.render.TextRenderer;
import de.lessvoid.nifty.layout.align.HorizontalAlign;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController;
import extensions.NetworkClient;
import extensions.NetworkClientListener;
import extensions.Server;
import extensions.games.AbstractGame;
import extensions.games.AbstractGame.GameStatus;
import extensions.games.GameManager;
import extensions.games.TanquesGame;

/**
 * 
 * @author Manu
 */
public class MainJME extends SimpleApplication implements ScreenController,
		NetworkClientListener {

	private Nifty _nifty;
	private ServerStatus _serverStatus = ServerStatus.Lobby;

	public static void main(String[] args) {
		MainJME app = new MainJME();
		app.start();
	}

	private AbstractGame _game = null;
	private Server _server;
	private Lobby _lobby;

	public MainJME() {
		_lobby = new Lobby();
	}

	@Override
	public void simpleInitApp() {
		Box b = new Box(new Vector3f(7, 7, -5), 10f, 10f, 5f);

		Geometry geom = new Geometry("Box", b);
		// geom.updateModelBound();

		Material mat = new Material(assetManager,
				"Common/MatDefs/Misc/SolidColor.j3md");
		mat.setColor("m_Color", ColorRGBA.DarkGray);
		geom.setMaterial(mat);

		rootNode.attachChild(geom);

		NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,
				inputManager, audioRenderer, guiViewPort);
		_nifty = niftyDisplay.getNifty();
		_nifty.fromXml("Interface/Nifty/HelloJme.xml", "start", this);
		guiViewPort.addProcessor(niftyDisplay);

		inputManager.setCursorVisible(true);

		registerGames();
	}

	private void registerGames() {
		GameManager.getInstance().registerGame(new TanquesGame("Tanques"));

		fillGamesPanel();
	}
	
	@Override
	public void simpleUpdate(float tpf) {
		NumberFormat numberFormat = NumberFormat.getInstance();
		numberFormat.setMaximumFractionDigits(4);
		setText("updateLabel", "Delta:" + numberFormat.format(tpf),
				HorizontalAlign.right);
		
		switch (_serverStatus)
		{
			case Lobby:
				
				break;
			case InGame:
				if (_game.getStatus() == GameStatus.Finished)
				{
					_serverStatus = ServerStatus.Lobby;
				}else
				{
					_game.update(tpf);
				}
				break;
		}
	}
	

	@Override
	public void simpleRender(RenderManager rm) {
		
		switch (_serverStatus)
		{
		case Lobby:
			break;
		case InGame:
			_game.render(rm);
			break;
		}
	}

	public void bind(Nifty nifty, Screen screen) {
		System.out.println("bind( " + screen.getScreenId() + ")");
	}

	public void onStartScreen() {
	}

	public void setText(String labelName, String text) {
		setText(labelName, text, null);
	}

	public boolean setText(String labelName, String text, HorizontalAlign align) {
		Element label = _nifty.getCurrentScreen().findElementByName(labelName);

		if (label == null) {
			return false;
		}

		label.getRenderer(TextRenderer.class).setText(text);

		if (align != null) {
			label.getRenderer(TextRenderer.class).setTextHAlign(align);
		}

		return true;
	}

	private void setStatusText(String text) {
		setText("statusLabel", text, HorizontalAlign.right);
	}

	public void onStartServerClick() {
		try {
			_server = new Server(7888, this);
			_server.setNewClientListener(this);

			setStatusText("Server started.");
		} catch (IOException ex) {
			setStatusText("Failed to open server!");
			Logger.getLogger(MainJME.class.getName()).log(Level.SEVERE, null,
					ex);
		}
	}

	private void fillGamesPanel() {
		DropDown<AbstractGame> dropDown = _nifty.getCurrentScreen()
				.findNiftyControl("dropDown", DropDown.class);

		for (AbstractGame game : GameManager.getInstance().getGames()) {
			dropDown.addItem(game);
		}
	}

	public AbstractGame getSelectedGame() {
		DropDown<AbstractGame> dropDown = _nifty.getCurrentScreen()
				.findNiftyControl("dropDown", DropDown.class);

		AbstractGame selectedGame = dropDown.getSelection();

		return selectedGame;
	}

	public String getIp() {
		String ret;
		try {
			ret = "Server '" + InetAddress.getLocalHost().getHostName() + "': "
					+ InetAddress.getLocalHost().getHostAddress();
		} catch (UnknownHostException ex) {
			Logger.getLogger(MainJME.class.getName()).log(Level.SEVERE, null,
					ex);
			ret = "Could not get server IP address.";
		}

		return ret;
	}

	public void onEndScreen() {
		System.out.println("onEndScreen");
	}

	public void quit() {
		_nifty.gotoScreen("end");
	}

	@Override
	public void destroy() {
		if (_server != null) {
			_server.close();
		}
	}

	public void hola() {
		System.out.println("Hola!");
	}

	public void onClientJoin(NetworkClient client) {
		_lobby.reserveSlot(client);
		int slot = _lobby.getSlotPos(client);

		setText("player" + slot + "Label", client.getHostAddress() + ":"
				+ client.getPort(), HorizontalAlign.left);
	}

	public void onClientDisconnected(NetworkClient client) {
		int slot = _lobby.kickSlot(client);

		setText("player" + slot + "Label", "[Free]", HorizontalAlign.center);
	}

	public void startGame() {
		System.out.println("Starting game:" + getSelectedGame());
		_serverStatus = ServerStatus.InGame;
		_game = getSelectedGame();
		_game.init(_lobby);
	}
}
